package proc

import (
	"context"
	"osiris/core/routine"
	"osiris/core/txpool"
	"osiris/logger"
	"osiris/p2p"
	"osiris/router"
	"sync"
	"time"
)

// TerminateProc 终止的routine.RoutineBatch
//
//	@return *routine.RoutineBatch
//	@return *sync.WaitGroup RoutineBatch执行完毕的信号
func TerminateProc() (*routine.OrderedRoutineBatch, *sync.WaitGroup) {
	exitWG := new(sync.WaitGroup)

	terminateServerRoutine := &routine.OrderedRoutine{
		Operation:    shutDownHttpServer,
		Args:         []interface{}{},
		AfterwardWGs: []*sync.WaitGroup{exitWG},
	}

	terminateNodeRoutine := &routine.OrderedRoutine{
		Operation:    shutDownP2PNode,
		Args:         []interface{}{},
		AfterwardWGs: []*sync.WaitGroup{exitWG},
	}

	closeTxPoolsRoutine := &routine.OrderedRoutine{
		Operation:    closeTxPools,
		Args:         []interface{}{},
		AfterwardWGs: []*sync.WaitGroup{exitWG},
	}

	routineBatch := &routine.OrderedRoutineBatch{}
	return routineBatch.Add(terminateServerRoutine).
			Add(terminateNodeRoutine).
			Add(closeTxPoolsRoutine),
		exitWG
}

// shutDownHttpServer 关闭http服务器
//
//	@param args
func shutDownHttpServer(args ...interface{}) {
	logger.Info(map[string]interface{}{"[proc] [shut Down HTTTP Server]": "shutting dowm for signal"})
	// 创建一个上下文对象，设置超时时间为 5 秒
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	// 关闭 HTTP 服务器
	if err := router.Server.Shutdown(ctx); err != nil {
		logger.Error(map[string]interface{}{"[proc] [shut Down HTTTP Server] router.Server.Shutdown()": err})
	} else {
		logger.Println("Http Server has been shut down")
		logger.Info((map[string]interface{}{"[proc] [shut Down HTTTP Server] router.Server.Shutdown()": "success"}))
	}
}

// shutDownP2PNode 关闭P2P节点
//
//	@param args
func shutDownP2PNode(args ...interface{}) {
	logger.Info(map[string]interface{}{"[proc] [shut down p2p node]": "shutting dowm for signal"})
	//关闭P2P节点
	if err := p2p.Close(); err != nil {
		logger.Error(map[string]interface{}{"[proc] [shut down p2p node]": err.Error()})
	} else {
		logger.Println("P2P Node has been shut down")
		logger.Info((map[string]interface{}{"[proc] [shut down p2p node]": "success"}))
	}
}

// closeTxPools 关闭本地交易池和远端交易池
//
//	@param args
func closeTxPools(args ...interface{}) {
	txpool.CloseTxPools()
	logger.Println("All txpools have been closed")
}
